package phoenics.manpads.stinger.controller;

import de.felixroske.jfxsupport.FXMLController;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import phoenics.manpads.stinger.dao.ProjectTableDao;
import phoenics.manpads.stinger.domain.po.ProjectTable;
import phoenics.manpads.stinger.domain.vo.ProjectTableVo;
import phoenics.manpads.stinger.model.DatabaseTable;
import phoenics.manpads.stinger.service.ImportMetaDataMysql;
import phoenics.manpads.stinger.service.PageList;

import java.net.URL;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @author Phoenics Chow
 * on 2019年01月23日
 */
@FXMLController
public class ImortDatabaseController  implements Initializable {
    private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ImortDatabaseController.class);
    private static int PAGESIZE=5;
    private String tablen=null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Autowired
    ProjectTableDao projectTableDao;
    @FXML
    ComboBox driverName;
    @FXML
    TextField url;
    @FXML
    TextField userName;
    @FXML
    TextField password;
    @FXML
    TableView dbTableView;
    @FXML
    TableColumn<DatabaseTable,Boolean> selectObj;
    @FXML
    TableColumn<DatabaseTable,String> tableName;
    @FXML
    TableColumn<DatabaseTable,String> readme;
    @FXML
    TableColumn<DatabaseTable,String> createTime;
    @FXML
    Pagination pageObj;
    @FXML
    TextField queryForName;
    @FXML
    CheckBox selectAll;
    private final ObservableList<DatabaseTable> coursData = FXCollections.observableArrayList();
    private final Set<String> importDatabaseName=new HashSet<>();
    private IntegerProperty indexPage;
    private IntegerProperty pageCount;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        dbTableView.setItems(coursData);
        indexPage = new SimpleIntegerProperty(-1);
        pageCount = new SimpleIntegerProperty(10000);
        driverName.getItems().addAll("mysql");
        driverName.setValue("mysql");
        selectObj.setCellFactory(CheckBoxTableCell.forTableColumn(selectObj));
        selectObj.setCellValueFactory(new PropertyValueFactory<>( "checkSelected" ));
        tableName.setCellValueFactory(new PropertyValueFactory<>("tableName"));
        readme.setCellValueFactory(new PropertyValueFactory<>("tableComment"));
        createTime.setCellValueFactory(new PropertyValueFactory<>("createTime"));
        pageObj.currentPageIndexProperty().addListener(( observable,oldValue,newValue)->{
            indexPage.setValue(newValue.intValue());
        });
        indexPage.addListener(( observable,oldValue,newValue)->{
            if(newValue.intValue()<0){
                return;
            }
            databaseLink(s->queryPage(s,tablen,newValue.intValue()+1,PAGESIZE));
        });
        pageCount.addListener(( observable,oldValue,newValue)->{
            if(newValue.intValue()<0){
                return;
            }
            pageObj.setPageCount(newValue.intValue());
        });
    }

    private String datacover(Timestamp t){
        return sdf.format(new Date(t.getTime()));
    }
    public void importAllTables(){
        tablen=null;
        indexPage.setValue(0);
        indexPage.setValue(-2);
    }
    private void queryPage(ImportMetaDataMysql importMetaData,String tableName,int page,int pagesize){
        PageList<Map<String, Object>> p= importMetaData.queryPage(tableName,page,pagesize);
        pageCount.setValue(p.getPages());
        coursData.clear();
        List<DatabaseTable> databaseTables=p.getList().stream().map(m->{
            DatabaseTable databaseTable=new DatabaseTable();
            databaseTable.setTableName(m.get("tableName").toString());
            databaseTable.setTableComment(m.get("tableComment").toString());
            databaseTable.setCreateTime(datacover((Timestamp)m.get("CreateTime")));
            databaseTable.checkSelectedProperty().addListener((ch,o,n)->{
                if(n){
                    importDatabaseName.add(databaseTable.getTableName());
                }else{
                    importDatabaseName.remove(databaseTable.getTableName());
                }
            });
            return databaseTable;
        }).collect(Collectors.toList());
        coursData.addAll(databaseTables);

    }
    public void databaseLink(Consumer<ImportMetaDataMysql> action){
        ImportMetaDataMysql importMetaData=takeImportMetaDataMysql();
        try{
            importMetaData.init();
            if(!importMetaData.testLink()){
                throw new Exception();
            }else{
                action.accept(importMetaData);
            }
        }catch (Exception e){
            takeMessageERROR();
        }
    }
    public void testDatabaseLink(){
        databaseLink(this::takeMessageOK);
    }

    private ImportMetaDataMysql takeImportMetaDataMysql(){
        String dbdriver="";
        if(driverName.getValue().equals("mysql")){
            dbdriver="com.mysql.cj.jdbc.Driver" ;
        }
        return new ImportMetaDataMysql(dbdriver,url.getText(),userName.getText(),password.getText());
    }
    private void takeMessageERROR(){
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("ERROR Dialog");
        alert.setHeaderText("测试连接数据库");
        alert.setContentText("数据库连接失败！！！");
        alert.showAndWait();
    }
    private void takeMessageOK(ImportMetaDataMysql importMetaData){
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("INFORMATION Dialog");
        alert.setHeaderText("测试连接数据库");
        alert.setContentText("数据库连接成功！！！");
        alert.showAndWait();
    }
    public void selectAllEvent(){
        if(dbTableView.getItems().size()==0){
            return;
        }
        for(int row=0;row<dbTableView.getItems().size();row++){
            ((BooleanProperty)selectObj.getCellObservableValue(row)).setValue(selectAll.isSelected());
        }
    }
    public void searchTable(){
        String t=queryForName.getText();
        this.tablen=null;
        if(StringUtils.isNotBlank(t)){
            tablen=t;
            indexPage.setValue(-1);
            pageCount.setValue(-1);
            indexPage.setValue(0);
        }
    }
    public void closeWindow(ActionEvent event){
        ((Stage)((Button)event.getTarget()).getScene().getWindow()).close();
    }
    public void importTables(ActionEvent event){
        if(importDatabaseName.size()==0) {
            return;
        }
        writeTablesToSystem(importDatabaseName);
        importDatabaseName.clear();
        closeWindow(event);
    }
    private void writeTablesToSystem(Set<String> importDatabaseName){
        ProjectTableVo projectTableVo=new ProjectTableVo();
        projectTableVo.setProjectId(123L);
        List<ProjectTable> ps=projectTableDao.findByConditions(projectTableVo);
        List<String> tabs=ps.stream().map(p->p.getTableName()).collect(Collectors.toList());
        importDatabaseName.stream().filter(n->tabs.contains(n)).forEach();
    }
}
